From e68b18aa4e38c86b934710d3004115833c651334 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 18 Dec 2016 01:45:07 +0100 Subject: [PATCH] vulkan: Move vertex data tracking to the pipeline subclass That way, different pipelines can draw different kinds of data. --- gsk/gskvulkanblendpipeline.c | 46 ++++++++++++++- gsk/gskvulkanblendpipelineprivate.h | 11 +++- gsk/gskvulkanpipeline.c | 2 +- gsk/gskvulkanrender.c | 38 +++++-------- gsk/gskvulkanrenderpass.c | 87 +++++++++++++++++++---------- gsk/gskvulkanrenderpassprivate.h | 9 +-- gsk/gskvulkanrenderprivate.h | 9 --- 7 files changed, 133 insertions(+), 69 deletions(-) diff --git a/gsk/gskvulkanblendpipeline.c b/gsk/gskvulkanblendpipeline.c index 9445be7fa9..eaaed67987 100644 --- a/gsk/gskvulkanblendpipeline.c +++ b/gsk/gskvulkanblendpipeline.c @@ -7,7 +7,17 @@ struct _GskVulkanBlendPipeline GObject parent_instance; }; -G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, G_TYPE_OBJECT) +typedef struct _GskVulkanVertex GskVulkanVertex; + +struct _GskVulkanVertex +{ + float x; + float y; + float tex_x; + float tex_y; +}; + +G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, GSK_TYPE_VULKAN_PIPELINE) static void gsk_vulkan_blend_pipeline_finalize (GObject *gobject) @@ -35,3 +45,37 @@ gsk_vulkan_blend_pipeline_new (GskVulkanPipelineLayout *layout, { return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_BLEND_PIPELINE, layout, shader_name, render_pass); } + +gsize +gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline) +{ + return sizeof (GskVulkanVertex) * 6; +} + +void +gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect) +{ + GskVulkanVertex *vertices = (GskVulkanVertex *) data; + + vertices[0] = (GskVulkanVertex) { rect->origin.x, rect->origin.y, 0.0, 0.0 }; + vertices[1] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 }; + vertices[2] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 }; + vertices[3] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 }; + vertices[4] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 }; + vertices[5] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y + rect->size.height, 1.0, 1.0 }; +} + +gsize +gsk_vulkan_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands) +{ + vkCmdDraw (command_buffer, + n_commands * 6, 1, + offset, 0); + + return n_commands * 6; +} diff --git a/gsk/gskvulkanblendpipelineprivate.h b/gsk/gskvulkanblendpipelineprivate.h index 23a54f9bf5..2d8bed5deb 100644 --- a/gsk/gskvulkanblendpipelineprivate.h +++ b/gsk/gskvulkanblendpipelineprivate.h @@ -1,7 +1,7 @@ #ifndef __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__ #define __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__ -#include +#include #include "gskvulkanpipelineprivate.h" @@ -17,6 +17,15 @@ GskVulkanPipeline * gsk_vulkan_blend_pipeline_new (GskVulk const char *shader_name, VkRenderPass render_pass); +gsize gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline); +void gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect); +gsize gsk_vulkan_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands); + G_END_DECLS #endif /* __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__ */ diff --git a/gsk/gskvulkanpipeline.c b/gsk/gskvulkanpipeline.c index cd9b62911d..11380780e4 100644 --- a/gsk/gskvulkanpipeline.c +++ b/gsk/gskvulkanpipeline.c @@ -73,7 +73,7 @@ gsk_vulkan_pipeline_new (GType pipeline_type, VkDevice device; - g_return_val_if_fail (!g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL); + g_return_val_if_fail (g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL); g_return_val_if_fail (layout != NULL, NULL); g_return_val_if_fail (shader_name != NULL, NULL); g_return_val_if_fail (render_pass != VK_NULL_HANDLE, NULL); diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index ec7a5b9362..723e5018cb 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -246,37 +246,37 @@ gsk_vulkan_render_upload (GskVulkanRender *self) } static gsize -gsk_vulkan_renderer_count_vertices (GskVulkanRender *self) +gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self) { - gsize count; + gsize n_bytes; GSList *l; - count = 0; + n_bytes = 0; for (l = self->render_passes; l; l = l->next) { - count += gsk_vulkan_render_pass_count_vertices (l->data); + n_bytes += gsk_vulkan_render_pass_count_vertex_data (l->data); } - return count; + return n_bytes; } static GskVulkanBuffer * -gsk_vulkan_render_collect_vertices (GskVulkanRender *self) +gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self) { GskVulkanBuffer *buffer; - GskVulkanVertex *vertices; + guchar *data; GSList *l; - gsize offset, count; + gsize offset, n_bytes; offset = 0; - count = gsk_vulkan_renderer_count_vertices (self); - buffer = gsk_vulkan_buffer_new (self->vulkan, sizeof (GskVulkanVertex) * count); - vertices = (GskVulkanVertex *) gsk_vulkan_buffer_map (buffer); + n_bytes = gsk_vulkan_renderer_count_vertex_data (self); + buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes); + data = gsk_vulkan_buffer_map (buffer); for (l = self->render_passes; l; l = l->next) { - offset += gsk_vulkan_render_pass_collect_vertices (l->data, vertices, offset, count - offset); - g_assert (offset <= count); + offset += gsk_vulkan_render_pass_collect_vertex_data (l->data, data, offset, n_bytes - offset); + g_assert (offset <= n_bytes); } gsk_vulkan_buffer_unmap (buffer); @@ -441,7 +441,7 @@ gsk_vulkan_render_draw (GskVulkanRender *self, command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool); - buffer = gsk_vulkan_render_collect_vertices (self); + buffer = gsk_vulkan_render_collect_vertex_data (self); vkCmdSetViewport (command_buffer, 0, @@ -476,17 +476,9 @@ gsk_vulkan_render_draw (GskVulkanRender *self, }, VK_SUBPASS_CONTENTS_INLINE); - vkCmdBindVertexBuffers (command_buffer, - 0, - 1, - (VkBuffer[1]) { - gsk_vulkan_buffer_get_buffer (buffer) - }, - (VkDeviceSize[1]) { 0 }); - for (l = self->render_passes; l; l = l->next) { - gsk_vulkan_render_pass_draw (l->data, self, self->layout, command_buffer); + gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer); } vkCmdEndRenderPass (command_buffer); diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 5290d0e600..0300cac093 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -2,6 +2,7 @@ #include "gskvulkanrenderpassprivate.h" +#include "gskvulkanblendpipelineprivate.h" #include "gskvulkanimageprivate.h" #include "gskrendernodeprivate.h" #include "gskrenderer.h" @@ -255,40 +256,49 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, } gsize -gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self) +gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) { - return self->render_ops->len * 6; -} + GskVulkanOp *op; + gsize n_bytes; + guint i; -static gsize -gsk_vulkan_render_op_collect_vertices (GskVulkanOpRender *op, - GskVulkanVertex *vertices) -{ - graphene_rect_t bounds; + n_bytes = 0; + for (i = 0; i < self->render_ops->len; i++) + { + op = &g_array_index (self->render_ops, GskVulkanOp, i); - gsk_render_node_get_bounds (op->node, &bounds); + switch (op->type) + { + case GSK_VULKAN_OP_FALLBACK: + case GSK_VULKAN_OP_SURFACE: + case GSK_VULKAN_OP_TEXTURE: + case GSK_VULKAN_OP_COLOR: + op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline)); + n_bytes += op->render.vertex_count; + break; - vertices[0] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y, 0.0, 0.0 }; - vertices[1] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 }; - vertices[2] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 }; - vertices[3] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 }; - vertices[4] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 }; - vertices[5] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, 1.0, 1.0 }; + default: + g_assert_not_reached (); + case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: + case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS: + continue; + } + } - return 6; + return n_bytes; } gsize -gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self, - GskVulkanVertex *vertices, - gsize offset, - gsize total) +gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, + guchar *data, + gsize offset, + gsize total) { GskVulkanOp *op; - gsize n; + gsize n_bytes; guint i; - n = 0; + n_bytes = 0; for (i = 0; i < self->render_ops->len; i++) { op = &g_array_index (self->render_ops, GskVulkanOp, i); @@ -299,8 +309,16 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self, case GSK_VULKAN_OP_SURFACE: case GSK_VULKAN_OP_TEXTURE: case GSK_VULKAN_OP_COLOR: - op->render.vertex_offset = offset + n; - op->render.vertex_count = gsk_vulkan_render_op_collect_vertices (&op->render, vertices + n + offset); + { + graphene_rect_t bounds; + + gsk_render_node_get_bounds (op->render.node, &bounds); + op->render.vertex_offset = offset + n_bytes; + gsk_vulkan_blend_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline), + data + n_bytes + offset, + &bounds); + n_bytes += op->render.vertex_count; + } break; default: @@ -310,11 +328,10 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self, continue; } - n += op->render.vertex_count; - g_assert (n + offset <= total); + g_assert (n_bytes + offset <= total); } - return n; + return n_bytes; } void @@ -349,10 +366,12 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, GskVulkanRender *render, + GskVulkanBuffer *vertex_buffer, GskVulkanPipelineLayout *layout, VkCommandBuffer command_buffer) { GskVulkanPipeline *current_pipeline = NULL; + gsize current_draw_index = 0; GskVulkanOp *op; guint i; @@ -383,11 +402,19 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, vkCmdBindPipeline (command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, gsk_vulkan_pipeline_get_pipeline (current_pipeline)); + vkCmdBindVertexBuffers (command_buffer, + 0, + 1, + (VkBuffer[1]) { + gsk_vulkan_buffer_get_buffer (vertex_buffer) + }, + (VkDeviceSize[1]) { op->render.vertex_offset }); + current_draw_index = 0; } - vkCmdDraw (command_buffer, - op->render.vertex_count, 1, - op->render.vertex_offset, 0); + current_draw_index += gsk_vulkan_blend_pipeline_draw (GSK_VULKAN_BLEND_PIPELINE (current_pipeline), + command_buffer, + current_draw_index, 1); break; case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h index fa012798b0..6c9cf36f46 100644 --- a/gsk/gskvulkanrenderpassprivate.h +++ b/gsk/gskvulkanrenderpassprivate.h @@ -4,7 +4,7 @@ #include #include -#include "gsk/gskvulkancommandpoolprivate.h" +#include "gsk/gskvulkanbufferprivate.h" #include "gsk/gskvulkanrenderprivate.h" G_BEGIN_DECLS @@ -23,9 +23,9 @@ void gsk_vulkan_render_pass_upload (GskVulk GskVulkanRender *render, GskVulkanUploader *uploader); -gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self); -gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self, - GskVulkanVertex *vertices, +gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self); +gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, + guchar *data, gsize offset, gsize total); @@ -33,6 +33,7 @@ void gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulk GskVulkanRender *render); void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, GskVulkanRender *render, + GskVulkanBuffer *vertex_buffer, GskVulkanPipelineLayout *layout, VkCommandBuffer command_buffer); diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index a85ee95772..5696dd3001 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -17,15 +17,6 @@ typedef enum { } GskVulkanPipelineType; typedef struct _GskVulkanRender GskVulkanRender; -typedef struct _GskVulkanVertex GskVulkanVertex; - -struct _GskVulkanVertex -{ - float x; - float y; - float tex_x; - float tex_y; -}; GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer, GdkVulkanContext *context); -- 2.30.2